--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_kirisama_marisa = General:new(extension, "hy_kirisama_marisa", "ten_k", 4, 4, General.Female)
    local light_shoot = fk.CreateSkill {
        name = "light_shoot",
    }
    light_shoot:addEffect(fk.CardUseFinished, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            local marks = player:getMark("light_shoot-turn")
            return player:hasSkill(light_shoot.name) and target == player and (type(marks) ~= "table" or not table.contains(marks, data.card.trueName)) and #data:getAllTargets() >= 2 and
                (not data.card:isVirtual() or #data.card.subcards > 0) and (data.card:isCommonTrick() or data.card.type == Card.TypeBasic) and
                not table.every(data:getAllTargets(), function(t)
                    return t.dead or player:isProhibited(t, data.card) or not data.card.skill:modTargetFilter(player, t, {}, data.card, data.extra_data or { bypass_distances = true })
                end)
        end,
        on_cost = function(self, event, target, player, data)
            local targets = table.filter(data:getAllTargets(), function(t)
                return not t.dead and player:canUseTo(data.card, t, { bypass_distances = true, bypass_times = true })
            end)
            local results = player.room:askToChoosePlayers(player, {
                targets = targets,
                min_num = 1,
                max_num = 1,
                prompt = "light_shoot_prompt:::" .. data.card.name,
                skill_name = light_shoot.name
            })
            event:setCostData(self, table.map(results, Util.IdMapper))
            return #event:getCostData(self) > 0
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local marks = player:getMark("light_shoot-turn")
            if type(marks) ~= "table" then
                marks = {}
            end
            table.insertIfNeed(marks, data.card.trueName)
            room:setPlayerMark(player, "light_shoot-turn", marks)
            local tos = table.map(event:getCostData(self), function(id)
                return room:getPlayerById(id)
            end)
            local useData = { ---@type UseCardDataSpec
                from = data.from,
                tos = tos,
                card = Fk:cloneCard(data.card.name),
                extraUse = true,
            }
            if data.card.name == "collateral" then
                useData.tos = {}
                local slash_target = data:getSubTos(data.tos[1])
                if #slash_target == 1 then
                    for i, t in ipairs(tos) do
                        useData.tos[i * 2 - 1] = t
                        useData.tos[i * 2] = slash_target[1]
                    end
                else
                    return
                end
            end
            room:useCard(useData)
        end,
    })
    local star_sky = fk.CreateSkill {
        name = "star_sky",
    }
    star_sky:addEffect(fk.GameStart, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(star_sky.name)
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            if #player:getPile("star_sky") > 0 then
                room:moveCards({
                    from = player,
                    ids = table.clone(player:getPile("star_sky")),
                    toArea = Card.DiscardPile,
                    moveReason = fk.ReasonJustMove,
                    skillName = star_sky.name,
                })
            end
            local cards = room:getNCards(7)
            room:moveCards({
                ids = cards,
                to = player,
                toArea = Card.PlayerSpecial,
                moveReason = fk.ReasonJustMove,
                skillName = star_sky.name,
                specialName = "star_sky",
                moveVisible = true,
                proposer = player,
            })
        end,
    })
    star_sky:addEffect(fk.RoundEnd, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(star_sky.name) and player.room:getBanner("RoundCount") % 2 == 0
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            if #player:getPile("star_sky") > 0 then
                room:moveCards({
                    from = player,
                    ids = table.clone(player:getPile("star_sky")),
                    toArea = Card.DiscardPile,
                    moveReason = fk.ReasonJustMove,
                    skillName = star_sky.name,
                })
            end
            local cards = room:getNCards(7)
            room:moveCards({
                ids = cards,
                to = player,
                toArea = Card.PlayerSpecial,
                moveReason = fk.ReasonJustMove,
                skillName = star_sky.name,
                specialName = "star_sky",
                moveVisible = true,
                proposer = player,
            })
        end,
    })
    star_sky:addEffect(fk.CardUsing, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            local marks = player:getTableMark("star_sky-turn")
            return player:hasSkill(star_sky.name) and player == target and not table.contains(marks, data.card.trueName) and
                (data.card:isCommonTrick() or (data.card.type == Card.TypeBasic and data.card.name ~= "jink")) and not table.every(player:getPile("star_sky"), function(id)
                    return Fk:getCardById(id).type ~= data.card.type
                end) and #player:getPile("star_sky") > 0 and data.card:getEffectiveId()
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local marks = player:getTableMark("star_sky-turn")
            table.insertIfNeed(marks, data.card.trueName)
            room:setPlayerMark(player, "star_sky-turn", marks)
            local cards = table.filter(player:getPile("star_sky"), function(id)
                return Fk:getCardById(id).type == data.card.type
            end)
            HY.ReplaceHandCardToTempNew(player, cards)
            local remove = HY.AskForCard(player, 1, 1, false, star_sky.name, false, nil, "star_sky_prompt_remove")
            HY.ReverseHandCardFromTempNew(player)
            room:moveCards({
                from = player,
                ids = remove,
                toArea = Card.DiscardPile,
                moveReason = fk.ReasonJustMove,
                skillName = star_sky.name,
            })
            local choices = { "star_sky_add", "star_sky_disreponsive", "star_sky_discard" }
            local valid = { "star_sky_add", "star_sky_disreponsive", "star_sky_discard" }
            local tos = {}
            for _, t in ipairs(data:getAllTargets()) do
                if not t:isNude() then
                    table.insertIfNeed(tos, t)
                end
            end
            if #tos == 0 then
                table.removeOne(valid, "star_sky_discard")
            end
            tos = {}
            for _, p in ipairs(room.alive_players) do
                if not table.contains(data:getAllTargets(), p) and player:canUseTo(data.card, p, { bypass_distances = true, bypass_times = true }) then
                    table.insertIfNeed(tos, p)
                    if data.card.trueName == "collateral" then
                        local slash_target = data:getSubTos(data.tos[1])
                        if #slash_target == 0 or not p:inMyAttackRange(slash_target[1]) then
                            table.removeOne(tos, p)
                        end
                    end
                end
            end
            if #tos == 0 then
                table.removeOne(valid, "star_sky_add")
            end
            local choice = room:askToChoice(player, {
                choices = valid,
                skill_name = star_sky.name,
                prompt = "star_sky_prompt_choice:::" .. data.card:toLogString(),
                all_choices = choices
            })
            if choice == "star_sky_add" then
                local addTargets = room:askToChoosePlayers(player, {
                    targets = tos,
                    min_num = 1,
                    max_num = 1,
                    prompt = "star_sky_prompt_add:::" .. data.card:toLogString(),
                    skill_name = star_sky.name,
                    cancelable = false
                })
                data:addTarget(addTargets[1], data:getSubTos(data.tos[1]))
            elseif choice == "star_sky_disreponsive" then
                data.disresponsiveList = room:getAlivePlayers()
            else
                local discardTargets = room:askToChoosePlayers(player, {
                    targets = table.filter(data:getAllTargets(), function(t)
                        return not t:isNude()
                    end),
                    min_num = 1,
                    max_num = 1,
                    prompt = "star_sky_prompt_discard",
                    skill_name = star_sky.name,
                    cancelable = false
                })
                local card = room:askToChooseCard(player, {
                    target = discardTargets[1],
                    flag = "he",
                    skill_name = star_sky.name
                })
                room:throwCard({ card }, star_sky.name, discardTargets[1], player)
            end
        end,
    })
    extension:loadSkillSkels { light_shoot, star_sky }
    hy_kirisama_marisa:addSkill("light_shoot")
    hy_kirisama_marisa:addSkill("star_sky")
    Fk:loadTranslationTable {
        ["hy_kirisama_marisa"] = "雾雨魔理沙",
        ["#hy_kirisama_marisa"] = "幻想与星与光",
        ["illustrator:hy_kirisama_marisa"] = "poppy",
        ["designer:hy_kirisama_marisa"] = "黑曜人形",
        ["cv:hy_kirisama_marisa"] = "",

        ["light_shoot"] = "光射",
        [":light_shoot"] = "每回合每牌名限一次，在你使用非虚拟的基本牌或普通锦囊牌结算结束后，若此牌包含至少两个目标，你可以视为对其中一个目标使用一张同名牌（无距离限制）。",
        ["light_shoot_prompt"] = "光射:你可以视为对其中一个目标使用一张%arg",

        ["star_sky"] = "星天",
        [":star_sky"] = "游戏开始时，你将牌堆顶七张牌置于你的武将牌上。每回合每牌名限一次，当你使用非虚拟的非【闪】基本牌或普通锦囊牌时，若“星天”牌中有相同类型的牌，你移去一张对应类型的“星天”牌并选择一项：1.为此牌增加一个目标；2.令此牌不可被响应；3.弃置此牌其中一个目标的一张牌。偶数轮结束时，你移去所有“星天”牌，然后将牌堆顶七张牌置于你的武将牌上。",
        ["star_sky_prompt_remove"] = "星天:你须移去一张牌",
        ["star_sky_add"] = "增加目标",
        ["star_sky_disreponsive"] = "不可响应",
        ["star_sky_discard"] = "弃置牌",
        ["star_sky_prompt_choice"] = "星天:你须为此%arg选择一项",
        ["star_sky_prompt_add"] = "星天:为%arg增加一个目标",
        ["star_sky_prompt_discard"] = "星天:弃置其中一名角色一张牌",
    }
end
